package spotGUI.optionsGUI;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.IOException;
import java.util.Vector;

import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import managers.FastProperties;
import managers.OptionsManager;
import net.tomahawk.ExtensionsFilter;
import net.tomahawk.XFileDialog;
import utils.StackTracePrinter;
import audio.AudioManager;
import audio.Sound;
import java.util.ResourceBundle;
import javax.swing.SwingConstants;

public class ChooseAudioDialog extends JDialog implements LineListener {

	private final JPanel contentPanel = new JPanel();

	private JCheckBox chckbxFadein;
	private JCheckBox chckbxFadeout;
	private JSlider sliderStartPoint;
	private JPanel buttonPane;
	private JSlider sliderLenght;

	private JTextField lblFileName;
	private JButton btnBrowse;
	private JLabel lblLenght;
	private JLabel lblStart;
	private JLabel lblStartPointDisplay;
	private JLabel lblSoundLenghtDisplay;
	private JButton btnPlay;
	private JButton btnStop;

	private FastProperties options;

	private String [] attributes; 

	private static final String [] SOUND_EXTENSIONS = {"wav"};
	private JButton btnDefault;

	private XFileDialog fileChooser;

	private Sound s; 
	/**
	 * @throws LineUnavailableException 
	 * @throws UnsupportedAudioFileException 
	 * @throws IOException 
	 */
	public ChooseAudioDialog(final JFrame owner, final String soundEventName) {
		super(owner, false);
		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentHidden(ComponentEvent arg0) {
				AudioManager.getSharedInstance().stop();
			}
		});

		setTitle(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.this.title")); //$NON-NLS-1$ //$NON-NLS-2$
		setResizable(false);
		setSize(new Dimension(440, 243));
		setLocationRelativeTo(null);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		GridBagLayout gbl_contentPanel = new GridBagLayout();
		gbl_contentPanel.columnWidths = new int[]{0, 0, 0, 0, 0};
		gbl_contentPanel.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
		gbl_contentPanel.columnWeights = new double[]{1.0, 1.0, 0.0, 1.0, Double.MIN_VALUE};
		gbl_contentPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		contentPanel.setLayout(gbl_contentPanel);

		options = OptionsManager.getSharedInstance().getOptionGroup("soundPopup");
		attributes = options.getProperty(soundEventName+".SOUNDPATH").split(",");

		btnPlay = new JButton(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.btnPlay.text")); //$NON-NLS-1$ //$NON-NLS-2$
		btnPlay.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
					playSound();
			}
		});
		btnPlay.setIcon(new ImageIcon(ChooseAudioDialog.class.getResource("/images/others/play.png")));
		btnPlay.setEnabled(true);
		GridBagConstraints gbc_btnPlay = new GridBagConstraints();
		gbc_btnPlay.gridheight = 2;
		gbc_btnPlay.insets = new Insets(0, 0, 0, 5);
		gbc_btnPlay.gridx = 2;
		gbc_btnPlay.gridy = 3;
		contentPanel.add(btnPlay, gbc_btnPlay);

		btnStop = new JButton(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.btnStop.text")); //$NON-NLS-1$ //$NON-NLS-2$
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				AudioManager.getSharedInstance().stop();
			}
		});
		btnStop.setIcon(new ImageIcon(ChooseAudioDialog.class.getResource("/images/others/stop.png")));
		btnStop.setEnabled(false);
		GridBagConstraints gbc_btnStop = new GridBagConstraints();
		gbc_btnStop.gridheight = 2;
		gbc_btnStop.gridx = 3;
		gbc_btnStop.gridy = 3;
		contentPanel.add(btnStop, gbc_btnStop);


		lblFileName = new JTextField();
		lblFileName.setEditable(false);
		GridBagConstraints gbc_lblFileName = new GridBagConstraints();
		gbc_lblFileName.gridwidth = 3;
		gbc_lblFileName.insets = new Insets(0, 0, 5, 5);
		gbc_lblFileName.fill = GridBagConstraints.HORIZONTAL;
		gbc_lblFileName.gridx = 0;
		gbc_lblFileName.gridy = 0;
		lblFileName.setName("Selected File");
		lblFileName.setText(attributes[0].substring(attributes[0].lastIndexOf("\\")+1));
		contentPanel.add(lblFileName, gbc_lblFileName);
		lblFileName.setColumns(10);

		fileChooser = new XFileDialog("Scegli audio");
		Vector<String> extensions = new Vector<String>();
		for (int i = 0; i < SOUND_EXTENSIONS.length; i++) {
			extensions.add(SOUND_EXTENSIONS[i]);
		}
		fileChooser.addFilters(new ExtensionsFilter("File audio", extensions));


		btnBrowse = new JButton(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.btnBrowse.text")); //$NON-NLS-1$ //$NON-NLS-2$
		btnBrowse.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String fileName = fileChooser.getFile();
				String directory = fileChooser.getDirectory();
				if (fileName != null) {
					lblFileName.setText(fileName);
					attributes[0] = directory+"\\"+fileName;
					System.out.println(attributes[0]);
					AudioManager.getSharedInstance().stop();
					try {
						playSound();
					} catch (Exception e) {
						//do nothing
					}
					btnPlay.setEnabled(true);
					setSlidersAndCheckBoxes();	
				}
			}
		});

		GridBagConstraints gbc_btnBrowse = new GridBagConstraints();
		gbc_btnBrowse.insets = new Insets(0, 0, 5, 0);
		gbc_btnBrowse.gridx = 3;
		gbc_btnBrowse.gridy = 0;
		contentPanel.add(btnBrowse, gbc_btnBrowse);

		lblStart = new JLabel(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.lblStart.text"));
		lblStart.setHorizontalAlignment(SwingConstants.RIGHT);
		GridBagConstraints gbc_lblStart = new GridBagConstraints();
		gbc_lblStart.fill = GridBagConstraints.HORIZONTAL;
		gbc_lblStart.insets = new Insets(0, 0, 5, 5);
		gbc_lblStart.gridx = 0;
		gbc_lblStart.gridy = 1;
		contentPanel.add(lblStart, gbc_lblStart);

		lblLenght = new JLabel(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.lblLenght.text")); //$NON-NLS-1$ //$NON-NLS-2$
		lblLenght.setHorizontalAlignment(SwingConstants.RIGHT);
		GridBagConstraints gbc_lblLenght = new GridBagConstraints();
		gbc_lblLenght.fill = GridBagConstraints.HORIZONTAL;
		gbc_lblLenght.insets = new Insets(0, 0, 5, 5);
		gbc_lblLenght.gridx = 0;
		gbc_lblLenght.gridy = 2;
		contentPanel.add(lblLenght, gbc_lblLenght);

		lblSoundLenghtDisplay = new JLabel();
		GridBagConstraints gbc_lblSoundLenghtDisplay = new GridBagConstraints();
		gbc_lblSoundLenghtDisplay.insets = new Insets(0, 0, 5, 0);
		gbc_lblSoundLenghtDisplay.gridx = 3;
		gbc_lblSoundLenghtDisplay.gridy = 2;
		contentPanel.add(lblSoundLenghtDisplay, gbc_lblSoundLenghtDisplay);

		lblStartPointDisplay = new JLabel();
		GridBagConstraints gbc_lblStartPointDisplay = new GridBagConstraints();
		gbc_lblStartPointDisplay.insets = new Insets(0, 0, 5, 0);
		gbc_lblStartPointDisplay.gridx = 3;
		gbc_lblStartPointDisplay.gridy = 1;
		contentPanel.add(lblStartPointDisplay, gbc_lblStartPointDisplay);


		sliderStartPoint = new JSlider();
		sliderStartPoint.setPaintTicks(true);
		sliderStartPoint.setMajorTickSpacing(60);
		sliderStartPoint.setMinorTickSpacing(10);
		GridBagConstraints gbc_sliderStartPoint = new GridBagConstraints();
		gbc_sliderStartPoint.gridwidth = 2;
		gbc_sliderStartPoint.insets = new Insets(0, 0, 5, 5);
		gbc_sliderStartPoint.gridx = 1;
		gbc_sliderStartPoint.gridy = 1;
		sliderStartPoint.setValue(new Integer (attributes[3]));
		contentPanel.add(sliderStartPoint, gbc_sliderStartPoint);


		sliderLenght = new JSlider();
		sliderLenght.setSnapToTicks(true);
		sliderLenght.setMinorTickSpacing(1);
		sliderLenght.setPaintTicks(true);
		GridBagConstraints gbc_sliderLenght = new GridBagConstraints();
		gbc_sliderLenght.gridwidth = 2;
		gbc_sliderLenght.insets = new Insets(0, 0, 5, 5);
		gbc_sliderLenght.gridx = 1;
		gbc_sliderLenght.gridy = 2;
		sliderLenght.setValue(new Integer (attributes[4]));
		contentPanel.add(sliderLenght, gbc_sliderLenght);



		chckbxFadeout = new JCheckBox(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.chckbxFadeout.text")); //$NON-NLS-1$ //$NON-NLS-2$
		chckbxFadeout.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				attributes[2] = Boolean.toString(chckbxFadeout.isSelected());
			}
		});
		GridBagConstraints gbc_chckbxFadeout = new GridBagConstraints();
		gbc_chckbxFadeout.anchor = GridBagConstraints.WEST;
		gbc_chckbxFadeout.insets = new Insets(0, 0, 5, 5);
		gbc_chckbxFadeout.gridx = 1;
		gbc_chckbxFadeout.gridy = 3;
		if (attributes[2].equals("true"))
			chckbxFadeout.setSelected(true);
		else
			chckbxFadeout.setSelected(false);
		contentPanel.add(chckbxFadeout, gbc_chckbxFadeout);

		chckbxFadein = new JCheckBox(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.chckbxFadein.text")); //$NON-NLS-1$ //$NON-NLS-2$
		chckbxFadein.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				attributes[1] = Boolean.toString(chckbxFadein.isSelected());
			}
		});
		GridBagConstraints gbc_chckbxFadein = new GridBagConstraints();
		gbc_chckbxFadein.anchor = GridBagConstraints.WEST;
		gbc_chckbxFadein.insets = new Insets(0, 0, 0, 5);
		gbc_chckbxFadein.gridx = 1;
		gbc_chckbxFadein.gridy = 4;
		if (attributes[1].equals("true"))
			chckbxFadein.setSelected(true);
		else
			chckbxFadein.setSelected(false);
		contentPanel.add(chckbxFadein, gbc_chckbxFadein);


		buttonPane = new JPanel();
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
		getContentPane().add(buttonPane, BorderLayout.SOUTH);

		JButton okButton = new JButton(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.okButton.text")); //$NON-NLS-1$ //$NON-NLS-2$
		okButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				options.put(soundEventName+".SOUNDPATH", attributes[0]+","+attributes[1]+","+attributes[2]+","+attributes[3]+","+attributes[4]);
				options.store();
				setVisible(false);
			}
		});

		btnDefault = new JButton(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.btnDefault.text")); //$NON-NLS-1$ //$NON-NLS-2$
		btnDefault.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				options.put(soundEventName+".SOUNDPATH", options.getProperty(soundEventName+"_def.SOUNDPATH"));
				dispose();
			}
		});
		buttonPane.add(btnDefault);
		okButton.setIcon(new ImageIcon(ChooseAudioDialog.class.getResource("/images/others/sound_accept.png")));
		okButton.setActionCommand("OK");
		buttonPane.add(okButton);
		getRootPane().setDefaultButton(okButton);

		JButton cancelButton = new JButton(ResourceBundle.getBundle("spotGUI.optionsGUI.messages").getString("ChooseAudioDialog.cancelButton.text")); //$NON-NLS-1$ //$NON-NLS-2$
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				dispose();
			}
		});
		cancelButton.setIcon(new ImageIcon(ChooseAudioDialog.class.getResource("/images/others/sound_remove.png")));
		cancelButton.setActionCommand("Cancel");
		buttonPane.add(cancelButton);


		playSound();

		sliderStartPoint.setMaximum((int)s.getLenght());
		sliderStartPoint.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent arg0) {
				int i = sliderStartPoint.getValue();
				lblStartPointDisplay.setText(i/60+" min "+i%60+" sec");
				attributes[3] = Integer.toString(i);
			}
		});

		sliderLenght.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent arg0) {
				lblSoundLenghtDisplay.setText(Integer.toString(((JSlider)arg0.getSource()).getValue())+" sec");
				if (sliderLenght.getValue() > (int)s.getLenght()-sliderStartPoint.getValue()) {
					sliderStartPoint.setValue((int)s.getLenght()-sliderLenght.getValue());
				}
				sliderStartPoint.setExtent(sliderLenght.getValue());
				attributes[4] = Integer.toString(sliderLenght.getValue());
			}
		});

		setSlidersAndCheckBoxes();

	}

	private void playSound () {
		try {
			
			Sound s = AudioManager.getSharedInstance().getSoundFactory().createSound(attributes[0], attributes);
			this.s = s;
			s.addListener(this);
			AudioManager.getSharedInstance().play(s);
		
		} catch (IOException e1) {
			StackTracePrinter.print(e1);
			lblFileName.setText("File not found. Choose another one.");
			btnPlay.setEnabled(false);
		} catch (Exception e) {
			StackTracePrinter.print(e);
			lblFileName.setText("Loading Error. Close and retry.");
			btnPlay.setEnabled(false);
		}
	}

	private void setSlidersAndCheckBoxes() {
		int lenght = (int)s.getLenght();
		sliderStartPoint.setMaximum((int)s.getLenght());
		sliderStartPoint.setValue(0);
		if (lenght == 0) {
			sliderLenght.setMinimum(1);
			sliderLenght.setMaximum(1);
			sliderLenght.setValue(1);
			disableCheckboxes();
		} else if (lenght == 1) {
			sliderLenght.setMinimum(1);
			sliderLenght.setMaximum(2);
			sliderLenght.setValue(2);
			disableCheckboxes();
		}
		else {
			sliderLenght.setMinimum(2);
			sliderLenght.setMaximum(Math.min(10, lenght));
			sliderLenght.setValue(2);
			chckbxFadein.setEnabled(true);
			chckbxFadeout.setEnabled(true);
		}
	}

	private void disableCheckboxes() {
		chckbxFadein.setSelected(false);
		chckbxFadeout.setSelected(false);
		chckbxFadein.setEnabled(false);
		chckbxFadeout.setEnabled(false);
	}

	@Override
	public void update(LineEvent event) {
		if (event.getType() == LineEvent.Type.START) {
			btnPlay.setEnabled(false);
			btnStop.setEnabled(true);
		} else if (event.getType() == LineEvent.Type.STOP) {
			btnPlay.setEnabled(true);
			btnStop.setEnabled(false);
		}

	}

}
